package com.moonbird.springboot.Utils.imageCreate;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.moonbird.springboot.Utils.imageCreate.util.MyUtil;
import okhttp3.HttpUrl;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.*;

public class ImageGenerator {

    public static final String hostUrl = "https://spark-api.cn-huabei-1.xf-yun.com/v2.1/tti";
    public static final String appid = "f9173867";
    public static final String apiSecret = "MTNjM2UxN2NkMmUyZTQzNDIxN2UxOGRm";
    public static final String apiKey = "a6e589a40b3eb2bad249c299fb440c5d";

    // 使用相对路径保存图片
    public static String generateImage(String description) throws Exception {
        String saveDir = "src/main/resources/in"; // 相对路径
        checkAndCreateDirectory(saveDir); // 检查并创建目录
        String authUrl = getAuthUrl(hostUrl, apiKey, apiSecret);
        System.out.println("Auth URL: " + authUrl);  // 打印 Auth URL
        String json = createRequestJson(description);
        System.out.println("Request JSON: " + json);  // 打印请求 JSON
        String res = MyUtil.doPostJson(authUrl, null, json);

        System.out.println("Response: " + res);  // 打印原始响应内容

        Gson gson = new Gson();
        JsonObject jsonObject = JsonParser.parseString(res).getAsJsonObject();

        System.out.println("Parsed JSON: " + jsonObject.toString());  // 打印解析后的 JSON 对象

        JsonObject header = jsonObject.getAsJsonObject("header");
        int code = header.get("code").getAsInt();
        String message = header.get("message").getAsString();

        if (code != 0) {
            System.out.println("错误: " + message);
            return "错误: " + message;  // 返回错误信息而不是空指针
        }

        JsonObject payload = jsonObject.getAsJsonObject("payload");
        if (payload != null && payload.has("choices")) {
            JsonObject choices = payload.getAsJsonObject("choices");
            if (choices != null && choices.has("text")) {
                JsonArray textArray = choices.getAsJsonArray("text");
                if (textArray != null && textArray.size() > 0) {
                    JsonObject firstTextObject = textArray.get(0).getAsJsonObject();
                    if (firstTextObject.has("content")) {
                        String base64Image = firstTextObject.get("content").getAsString();
                        return saveBase64Image(base64Image, saveDir + "/output.png");
                    } else {
                        System.out.println("第一个文本对象中没有找到内容字段。");
                        return "第一个文本对象中没有找到内容字段。";
                    }
                } else {
                    System.out.println("没有文本数组或文本数组为空。");
                    return "没有文本数组或文本数组为空。";
                }
            } else {
                System.out.println("在有效载荷中没有找到选项对象。");
                return "在有效载荷中没有找到选项对象。";
            }
        } else {
            System.out.println("JSON 对象中没有找到有效载荷字段。");
            return "JSON 对象中没有找到有效载荷字段。";
        }
    }

    private static String getAuthUrl(String hostUrl, String apiKey, String apiSecret) throws Exception {
        URL url = new URL(hostUrl);
        SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = format.format(new Date());

        String preStr = "host: " + url.getHost() + "\n" + "date: " + date + "\n" + "POST " + url.getPath() + " HTTP/1.1";
        Mac mac = Mac.getInstance("HmacSHA256");
        SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
        mac.init(spec);

        byte[] hexDigits = mac.doFinal(preStr.getBytes(StandardCharsets.UTF_8));
        String sha = Base64.getEncoder().encodeToString(hexDigits);
        String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"",
                apiKey, "hmac-sha256", "host date request-line", sha);

        HttpUrl httpUrl = Objects.requireNonNull(HttpUrl.parse("https://" + url.getHost() + url.getPath())).newBuilder()
                .addQueryParameter("authorization", Base64.getEncoder().encodeToString(authorization.getBytes(StandardCharsets.UTF_8)))
                .addQueryParameter("date", date)
                .addQueryParameter("host", url.getHost())
                .build();

        return httpUrl.toString();
    }

    private static String createRequestJson(String description) {
        JsonObject header = new JsonObject();
        header.addProperty("app_id", appid);
        header.addProperty("uid", UUID.randomUUID().toString().substring(0, 15));

        JsonObject chat = new JsonObject();
        chat.addProperty("domain", "s291394db");
        chat.addProperty("temperature", 0.5);
        chat.addProperty("max_tokens", 4096);
        chat.addProperty("width", 1024);
        chat.addProperty("height", 1024);

        JsonObject parameter = new JsonObject();
        parameter.add("chat", chat);

        JsonObject message = new JsonObject();
        JsonArray textArray = new JsonArray();
        JsonObject textObject = new JsonObject();
        textObject.addProperty("role", "user");
        textObject.addProperty("content", description);
        textArray.add(textObject);
        message.add("text", textArray);

        JsonObject payload = new JsonObject();
        payload.add("message", message);

        JsonObject request = new JsonObject();
        request.add("header", header);
        request.add("parameter", parameter);
        request.add("payload", payload);

        return request.toString();
    }

    private static String saveBase64Image(String base64Image, String destinationFile) throws Exception {
        // 获取当前工作目录
        String currentDir = System.getProperty("user.dir");
        String destinationPath = currentDir + File.separator + destinationFile;

        File file = new File(destinationPath);
        File parentDir = file.getParentFile();
        if (!parentDir.exists()) {
            parentDir.mkdirs();
        }

        byte[] decodedBytes = Base64.getDecoder().decode(base64Image);
        try (OutputStream os = new FileOutputStream(file)) {
            os.write(decodedBytes);
        }
        return file.getAbsolutePath();
    }

    public static byte[] getImageBytes(String imagePath) {
        File file = new File(imagePath);
        byte[] bytes = new byte[(int) file.length()];
        try {
            FileInputStream fis = new FileInputStream(file);
            fis.read(bytes);
            fis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bytes;
    }

    private static void checkAndCreateDirectory(String path) {
        if (!Files.exists(Paths.get(path))) {
            try {
                Files.createDirectories(Paths.get(path));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
